#include "common.h"

/**************************************************
	全局变量
**************************************************/
INSTALL_ARGS_STR g_installArgs = {0};
VEHICLE_ARGS_STR g_vehicleArgs = {0};
SET_ARGS_STR set_argStr = {{0}};
extern SOCK_NODE *head;

TERM_REG_FM tmReg_fm;//0x0100

POS_INFO pos_info = {0};
POS_INFO_FM pos_infoFm;//0x0200

POSINFO_SERCHRPY posInfo_serch = {0};//0x0201
POSINFO_SERCHRPY_FM posInfo_serchFm;

UINT8 eventId, answerId, type, flags;
INT8 eleCnt[300] = {0};
UINT32 status;

ELEC_BILL_UP elcBill_up ;//0x0701

DRIVER_INFO drvInfo; 
DRIVER_INFO_FM drvInfoFm;//0x0702

MEDIA_EVENT_UP medEvent;
MEDIA_EVENT_FM medEventFm;

MEDIA_DAT_UP medDat;
MEDIA_DAT_FM medDatFm;

TRAV_RECD_UP trvRecd;
MYSQL_STRUC mys_stc = {0};

/*********************************************************
		函数原型
**********************************************************/
//remeber free(pMsg->pbody)
INT32 assign_jt808msg(JT808_MSG_PKG *pMsg, INT8 *pDat, INT32 datLen)
{
	UINT16 attr, msgHdLen, bodyLen;
	INT32 msglen, r = 0;
	if(pDat == NULL)
		return -1;
	if(pDat[0] != 0x7e && pDat[datLen-1] != 0x7e)
		return -1;
	
	msglen = recover_jt808msg(pDat, datLen);
	r = check_crc((UINT8 *)pDat, msglen);
	if(r == -1){
		E(" Check code error.");
		return -1;
	}

	attr = ntohs(*(UINT16 *)(pDat+3));
	if(attr & MSG_ENC_FLAG)
	{
		msgHdLen = 16;
	}
	else 
	{
		msgHdLen = 12;
	}
	bodyLen = attr & 0x03ff;
	
	pMsg->pbody = (UINT8 *)malloc(sizeof(UINT8)*bodyLen + 1);
	if(NULL == pMsg->pbody){
		perror("malloc().");
		exit(1);
	}
/*
	if(msglen != msgHdLen + 3 + bodyLen)
	{
		return -1;
	}
	else	
*/
	{
		pMsg->flagst = 0x7e;
		pMsg->flagend = 0x7e;
		pMsg->head.id = ntohs(*(UINT16 *)(pDat+1));
		pMsg->head.attr = attr;
		memcpy(pMsg->head.phone, pDat+5, sizeof(pMsg->head.phone));
		pMsg->head.seqNum = ntohs(*(UINT16 *)(pDat+11));
		if(attr & MSG_ENC_FLAG)
		{
			pMsg->head.enc.total = (UINT16)ntohs(*(UINT16 *)(pDat+13));
			pMsg->head.enc.num = (UINT16)ntohs(*(UINT16 *)(pDat+15));
			memcpy(pMsg->pbody, (pDat+17), bodyLen);
			return 0;
		}
		else
		{
			memcpy(pMsg->pbody, (pDat+13), bodyLen);
		}
		pMsg->crc = pDat[msglen-2];

		return 0;
	}
}

INT32 send_ack_msg(INT32 sfd, UINT8 *pMsg, INT32 msgLen)
{
	INT32 r;

	do{
		r = send(sfd, pMsg, msgLen, 0);
	}
	while(r == -1 && errno == EINTR);	
	if(r == -1){
		free(pMsg);
		perror("malloc().");
		return -1;
	}
	free(pMsg);
	return 0;
}

INT32 msg_analyze(JT808_MSG_PKG *pJt808, INT32 sfd)
{
	UINT16 msgId;
	UINT8 *p_b = NULL;
	INT32 ret, vid, color, fd;
	SOCK_NODE sock;
	INT8 tmpSim[16] = {'\0'}, sim[16] = {'\0'};	
	INT8 lisence[24] = {0}, str[8] = {0};
	INT8 sql_cmd[BUF_SIZE], result = 0x0;

	if(pJt808 == NULL)
		return -1;
	if (mys_stc.conn == NULL)
		initial_mysql(&mys_stc);
	
	memset(sql_cmd, 0, sizeof(sql_cmd));
	memset(g_installArgs.terminalTel, 0x00, 6);
	memcpy(g_installArgs.terminalTel, pJt808->head.phone, 6);
	
	simHex_convert_str(g_installArgs.terminalTel, tmpSim);
	//only in the main land of china
	memcpy(sim, &tmpSim[1], strlen(tmpSim) - 1);

#if 1
	memset(&sock, 0, sizeof(sock));
	sock.sfd = sfd;
	memcpy(sock.sim, sim, strlen((const char *)sim));

	ret = malloc_node_num(head, 1, &sock);
	if(ret == -1){
		E(" Malloc_node_num error.");
		return -1;
	}
#endif
	if(pJt808->head.attr & MSG_ENC_FLAG){
		ret = encPkg_handle(pJt808, p_b, sfd);
		if(ret == -1)
			E(" EncPkg_handle erron.");
	}else
		p_b = pJt808->pbody;	

	msgId = pJt808->head.id;

	E(" MsgId: %x.  Sim:%s", msgId, sim);
	switch (msgId){
		case 0x0001:
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, 0, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
		case 0x0002:
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, 0, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
		case 0x0003:
			/* 0x8001 platform common reply.*/
			sprintf(sql_cmd, "select * from resister where sim = '%s';", sim);
			ret = mysql_terMlogout(sql_cmd, sim);

			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
		case 0x0100:
			/* 0x8100 terminal register reply.*/
			//TODO:
			//memcpy((INT8 *)g_installArgs.Akey, "20120410", 8);
			//term_register(p_b);
			//strcpy(g_installArgs.Akey, "20120410");
			//ret = term_register_ack(pJt808->head.seqNum, 0, g_installArgs.Akey, sfd);//crc error.

			memset(&tmReg_fm, 0x0, sizeof(tmReg_fm));
			ret = term_register(p_b);
			term_register_trans(&tmReg_fm);

			result = term_reg_fun(&tmReg_fm, sim);
			switch(result){
				case 0: 
					memset(sql_cmd, 0, sizeof(sql_cmd));
					sprintf(sql_cmd, "select autuher from resister where sim = '%s';", sim);
					get_field(sql_cmd, (INT8 *)g_installArgs.Akey);

					ret = term_register_ack(pJt808->head.seqNum, result, g_installArgs.Akey, sfd);
					if(ret == -1){
						E(" Send package error.");
						return -1;
					}
					break;
				case 1: case 2: case 3: case 4:
					memset(g_installArgs.Akey, 0, sizeof(g_installArgs.Akey));
					ret = term_register_ack(pJt808->head.seqNum, result, g_installArgs.Akey, sfd);//crc error.
					if(ret == -1){
						E(" Send package error.");
						return -1;
					}
					//close(sfd);
					break;
				default:
					close(sfd);
					break;
			}

			break;
#if 1
		case 0x0102:
			/* 0x8001 platform common reply.*/
			memset(g_installArgs.Akey, 0, sizeof(g_installArgs.Akey));
			ret = term_authen(p_b);

			sprintf(sql_cmd, "select autuher from resister where sim = '%s';", sim);
			ret = contrast_Akey(sql_cmd, (INT8 *)g_installArgs.Akey);

			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;

		case 0x0104:
			/* 0x8001 platform common reply.*/
			ret = search_term_argRpy(pJt808, &set_argStr, vid, sfd);
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#endif
		case 0x0200:
			memset(&pos_info, 0, sizeof(pos_info));
			memset(&pos_infoFm, 0, sizeof(pos_infoFm));

			ret = posInfo_report(pJt808, &pos_info);
			posInfo_report_trans(&pos_info, &pos_infoFm);
#if 1
			sprintf(sql_cmd, "select id from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			vid = strtoul((const char *)str, NULL, 10);
			
			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "insert position values(null, '%d', '%d', '%f', '%f', '%f', '%d', '%s',	\
				'%d', '%d');", pos_infoFm.base_fm.altitude, pos_infoFm.base_fm.direction,	\
				pos_infoFm.base_fm.lat, pos_infoFm.base_fm.lng, pos_infoFm.base_fm.speed,	\
				pos_infoFm.base_fm.status, pos_infoFm.base_fm.time, vid, pos_infoFm.base_fm.warning);

			ret = mysql_fun(sql_cmd);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			memcpy(sql_cmd, "Hello, World.", sizeof("Hello, World."));
			sprintf(sql_cmd, "%d,%d,%f,%f,%d,%f,%d,%s;", pos_infoFm.base_fm.warning, pos_infoFm.base_fm.status,	\
				pos_infoFm.base_fm.lng, pos_infoFm.base_fm.lat, pos_infoFm.base_fm.altitude, pos_infoFm.base_fm.speed,	\
					pos_infoFm.base_fm.direction, pos_infoFm.base_fm.time);

			fd = open(NAME_FIFO_2, O_WRONLY | O_NONBLOCK, 0);
			if(fd == -1){
				if(errno == ENXIO)
					E(" Open error: no reading process.");
			}
			ret = strlen((const char *)sql_cmd);
			if((ret = write(fd, sql_cmd, ret)) == -1)
			{
				if(errno == EAGAIN)
					E(" The fifo2 has not been read yet.Please try later");
			}

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "insert tposition values(null, '%d', '%d', '%f', '%f', '%f', '%d',	\
				'%s', '%d');", vid, pos_infoFm.base_fm.direction, pos_infoFm.base_fm.lat,	\
				pos_infoFm.base_fm.lng, pos_infoFm.base_fm.speed, pos_infoFm.base_fm.status,	\
				pos_infoFm.base_fm.time, pos_infoFm.base_fm.warning);

			ret = mysql_fun(sql_cmd);
#endif
			//platform common rpy	
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#if 1
		case 0x0201:
			memset(&posInfo_serch, 0, sizeof(posInfo_serch));
			memset(&posInfo_serchFm, 0, sizeof(posInfo_serchFm));

			ret = posInfo_search_rpy(pJt808, &posInfo_serch);
			posInfo_search_trans(&posInfo_serch, &posInfo_serchFm);

			sprintf(sql_cmd, "select id from vehicle sim = '%s';", sim);
			get_field(sql_cmd, str);
			vid = strtoul((const INT8 *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "insert searchposition values(null, '%d', '%d', '%f', '%f',	\
				'%f', '%d', '%s', '%d', '%d');", posInfo_serchFm.altitude, posInfo_serchFm.direction,	\
				posInfo_serchFm.lat, posInfo_serchFm.lng, posInfo_serchFm.speed, posInfo_serchFm.status,	\
					posInfo_serchFm.time, vid, posInfo_serchFm.warning);
			ret = mysql_fun(sql_cmd);

			//platform common rpy	
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#endif
#if 1
		case 0x0301:
			eventId = *(UINT8 *)p_b;
	
			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const char *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "update eventset set status = '%d' where car_color = '%d' && car_no = '%s';",	\
				eventId, color, lisence);			
			ret = mysql_fun(sql_cmd);

			//platform common rpy	
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;


		case 0x0302:

			p_b += 2;
			answerId = *(UINT8 *)(p_b);

			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const char *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "update questionset set answer = '%d' where car_color = '%d' && car_no = '%s';",	\
				answerId, color, lisence);			
			ret = mysql_fun(sql_cmd);

			//platform common rpy	
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#endif
#if 1
		case 0x0303:
			type = *(UINT8 *)p_b++;
			flags = *(UINT8 *)p_b;

			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const INT8 *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "insert seviceselect values(null, '%d', '%s', '%d', '%d');",	\
				color, lisence, type, flags);
			ret = mysql_fun(sql_cmd);

			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;

		case 0x0500:
			p_b += 4;
			
			status = ntohl(*(UINT32 *)p_b);
			status = status & (1 << 12);
			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const INT8 *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "update control set status = '%d' where car_color = '%d' && car_no = '%s';",	\
				status, color, lisence);
			ret = mysql_fun(sql_cmd);
			
			//platform common rpy	
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#endif
		case 0x0700:
			memset(&trvRecd, 0, sizeof(trvRecd));
			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const INT8 *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);

			ret = traver_record_up(p_b, &trvRecd, color, lisence);

			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#if 1
		case 0x0701:
			ret = elec_bill_up(p_b, &elcBill_up);

			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const char *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);

			sprintf(eleCnt, "%s", elcBill_up.elcBillCtent);
			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "insert transport values(null, '%d', '%s', '%s', now());",	\
								color, lisence, eleCnt);			
			ret = mysql_fun(sql_cmd);

			/* platform common reply.*/
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#endif
#if 1
		case 0x0702:
			memset(&drvInfo, 0, sizeof(drvInfo));
			memset(&drvInfoFm, 0, sizeof(drvInfoFm));
			
			ret = drvInfo_upload(p_b, &drvInfo);
			drvInfo_upload_trans(&drvInfo, &drvInfoFm);

			sprintf(sql_cmd, "insert driver vaulues(null, now(), '%s', '%s', '%s', '%s');",	\
				drvInfoFm.idnumber, drvInfoFm.issue, drvInfoFm.license, drvInfoFm.name);
			ret = mysql_fun(sql_cmd);

			/* platform common reply.*/
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
 			break;

		case 0x0800:
			memset(&medEvent, 0, sizeof(medEvent));
			memset(&medEventFm, 0, sizeof(medEventFm));

			ret = media_event_upload(p_b, &medEvent);
			media_event_trans(&medEvent, &medEventFm);

			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const INT8 *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);			

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "insert meidaevent values(null, '%d', '%s', '%d', now(), '%s', '%s', '%s', \
				'%s');", color, lisence, medEventFm.channel, medEventFm.dataid, \
				medEventFm.event, medEventFm.format, medEventFm.type);

			ret = mysql_fun(sql_cmd);
			if(ret == -1){
				E(" Insert data failed!");
				return -1;
			}

			/* platform common reply.*/
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;
#endif
#if 1
		case 0x0801:
			memset(&medDat, 0, sizeof(medDat));
			memset(&medDatFm, 0, sizeof(medDatFm));

			ret = media_data_upload(p_b, &medDat);
			media_data_trans(&medDat, &medDatFm);

			sprintf(sql_cmd, "select color from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, str);
			color = strtoul((const char *)str, NULL, 10);

			memset(sql_cmd, 0, sizeof(sql_cmd));
			sprintf(sql_cmd, "select lisence from vehicle where sim = '%s';", sim);
			get_field(sql_cmd, lisence);			

			sprintf(sql_cmd, "insert meida values(null, '%d', '%s', '%s', now(), '%s', '%s', '%s', \
				'%d', '%s');", color, lisence, medDatFm.content, medDatFm.dataid, medDatFm.event,	\
					medDatFm.format, medDatFm.pos_id, medDatFm.type);
			ret = mysql_fun(sql_cmd);
			if(ret == -1){
				E("insert data failed!");
				return -1;
			}

			/* platform common reply.*/
			ret = platform_common_ack(pJt808->head.seqNum, pJt808->head.id, ret, sfd);
			if(ret == -1){
				E(" Send package error.");
				return -1;
			}
			break;

		case 0x0802:
			break;
#endif
		default:
			close(sfd);
			break; 
	}
	free(pJt808->pbody);

	return 0;
}
